home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 46 / Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso / -in_the_mag- / banging_the_metal / draw_logic / draw_asm next >
Text File  |  1996-08-20  |  8KB  |  188 lines

  1. * QL WORLD DIY TOOLKIT - FAST pixel graphics routines
  2. * Version 1.6, Copyright 1989,90 Simon N Goodwin.
  3. * Modified 10/9/89 to support Thor XVI MODE 12.
  4. * Modified 19/7/90 to suit Metacomco's Assembler.
  5. *
  6. xstore     equ      84              Offsets of old X & Y
  7. ystore     equ      78              in the channel block
  8. *
  9. start      lea.l   define,a1
  10.            move.w  $110,a2         BP.INIT vector
  11.            jmp     (a2)
  12. *
  13. draw       lea.l   drawer,a4
  14.            bra.s   get_params
  15. plot       lea.l   plotter,a4
  16. *
  17. * Handler for 2 or 3 parameters
  18. *
  19. get_params move.w  $112,a2         Vector to get integers
  20.            jsr     (a2)            CA.GTINT
  21.            bne.s   bad_exit
  22.            moveq   #1,d0           First assume channel 1
  23.            subq.w  #2,d3           At least 2 parameters?
  24.            beq.s   get_coords      Exactly 2,  use #1
  25.            bmi.s   bad_param       Less than 2: an error  
  26.            subq.w  #1,d3           Only 1 parameter left?
  27.            bne.s   bad_param       No, too many, complain
  28.            move.w  0(a1,a6.l),d0   Get BASIC channel No.
  29.            addq.l  #2,a1           Discard channel param.
  30. get_coords move.w  0(a1,a6.l),d1   Get X co-ordinate
  31.            move.w  2(a1,a6.l),d2   Get Y co-ordinate
  32. *
  33. * Convert channel number in D0 to ID in A0 and call EXTOP
  34. *
  35. chan_sel   mulu    #40,d0          Channel table size
  36.            add.l   $30(a6),d0      Add base offset
  37.            cmp.l   $34(a6),d0 
  38.            bge.s   what_chan       Past end of table?
  39.            move.l  0(a6,d0.l),d0
  40.            bmi.s   what_chan       Negative if closed
  41. call_extop move.l  d0,a0           A0 is channel ID
  42.            move.l  a4,a2           Address of routine
  43.            moveq   #-1,d3          Allow infinite time
  44.            moveq   #9,d0           SD.EXTOP key
  45.            trap    #3              Call the device driver
  46.            rts                      Return D0 from EXTOP
  47. *
  48. bad_param  moveq   #-15,d0         BAD PARAMETER error
  49.            rts
  50. what_chan  moveq   #-6,d0          CHANNEL NOT OPEN error
  51. bad_exit   rts                      Error code is in D0
  52. *
  53. * Line DRAW routine
  54. *
  55. drawer     move.w  xstore(a0),d4   Fetch previous X
  56.            move.w  ystore(a0),d5   Fetch previous Y
  57.            bsr     range_chk       Line must fit window
  58. find_DX    suba.l  a2,a2           DX := 0
  59.            sub.w   d4,d1
  60.            beq.s   set_X_step
  61.            bmi.s   neg_DX
  62.            addq.l  #1,a2           A2 := SIGN( Delta X )
  63.            bra.s   set_X_step
  64. neg_DX     subq.l  #1,a2
  65.            neg.w   d1              D1 := ABS( Delta X )
  66. set_X_step btst    #3,52(a6)       Check mode (SV.MCSTA)
  67.            beq.s   find_DY         MODE 4, D1 & A2 are OK
  68.            adda.l  a2,a2           MODE 8/12, double X step
  69.            ror.w   #1,d1           And halve X dot count
  70. find_DY    suba.l  a3,a3           DY := 0
  71.            sub.w   d5,d2
  72.            beq.s   find_DD
  73.            bmi.s   neg_DY
  74.            addq.l  #1,a3           A3 := SIGN( Delta Y )
  75.            bra.s   find_DD
  76. neg_DY     subq.l  #1,a3
  77.            neg.w   d2              D2 := ABS( Delta Y )
  78. find_DD    cmp.w   d1,d2           D1 := MAX( D1, D2 )
  79.            bhi.s   y_bigger
  80. no_match   move.w  a2,a4           DDX := DX
  81.            suba.l  a5,a5           DDY := 0
  82.            bra.s   find_TEMP
  83. y_bigger   exg     d1,d2           D1 := MAX( D1,D2 )
  84.            suba.l  a4,a4           DDX := 0
  85.            move.w  a3,a5           DDY := DY
  86. find_TEMP  move.w  d1,d0
  87.            asr.w   #1,d0           TEMP := STEPS DIV 2
  88.            move.w  d2,d6           D6 := PARTS
  89.            move.w  d1,d2
  90.            subq.w  #1,d2           D2 is DOT for DBRA
  91.            bmi.s   null_draw       Exit if line length=0
  92.            exg     d1,d4           OLDX = D1; STEPS = D4
  93.            exg     d2,d5           OLDY = D2; DOT = D5
  94. *
  95. * Now draw a line of D5 pixels; D1,D2 = X,Y of next point
  96. *
  97. dot_loop   add.w   d6,d0           TEMP := TEMP + PARTS
  98.            cmp.w   d4,d0           Flag TEMP - STEPS
  99.            bcs.s   use_DD
  100.            sub.w   d4,d0           TEMP := TEMP - STEPS
  101.            add.w   a2,d1           OLDX := OLDX + DX
  102.            add.w   a3,d2           OLDY := OLDY + DY
  103.            bra.s   do_dot
  104. *
  105. use_DD     add.w   a4,d1           OLDX := OLDX + DDX
  106.            add.w   a5,d2           OLDY := OLDY + DDY
  107. do_dot     movem.w d1-d2,-(a7)     Preserve OLDX & OLDY
  108.            bsr.s   plot_pixel
  109.            movem.w (a7)+,d1-d2     Restore OLDX & OLDY
  110.            dbra    d5,dot_loop
  111. null_draw  moveq   #0,d0
  112.            rts
  113. *
  114. * Co-ordinate checker; D1=X, D2=Y, ERR.OR if beyond window
  115. *
  116. range_chk  tst.b   51(a6)          Test SV.SCRST
  117.            bne.s   screen_off      Abort if CTRL-F5 set
  118.            tst.w   d2              Check Y >= 0
  119.            bmi.s   range_err
  120.            cmp.w   30(a0),d2       Check Y < CH.HEIGHT 
  121.            bcc.s   range_err
  122.            tst.w   d1              Check X >= 0
  123.            bmi.s   range_err
  124.            cmp.w   28(a0),d1       Check X < CH.WIDTH
  125.            bcc.s   range_err
  126.            move.w  #$8080,d7       Set MODE 4 pixel mask
  127.            btst    #3,52(a6)       Check MODE (SV.MCSTA)
  128.            beq.s   range_ok        MODE 4, no problems
  129.            bclr    #0,d1           MODE 8/12, X must be EVEN
  130.            btst    #2,52(a6)       Test Thor MODE 12 bit
  131.            beq.s   not_a_thor
  132.            move.w  #$C0C0,d7       Use the Thor mask
  133. not_a_thor move.b  #$C0,d7         Mask 8 colours
  134. range_ok   add.w   24(a0),d1       Add window offset to X
  135.            add.w   26(a0),d2       Add window offset to Y
  136.            move.w  d1,xstore(a0)   Store end X on SD.XORG
  137.            move.w  d2,ystore(a0)   Store end Y on SD.YORG
  138.            rts
  139. *
  140. screen_off moveq   #-1,d0          NOT COMPLETE error
  141.            bra.s   quick_exit
  142. range_err  moveq   #-4,d0          OUT OF RANGE error
  143. quick_exit addq.l  #4,a7           Return to after TRAP
  144.            rts
  145. *
  146. * Pixel PLOT code, uses A0, A6, D7; alters A1, D1, D2, D3
  147. *
  148. plotter    bsr.s   range_chk
  149.            moveq   #0,d0           Preset ERR.OK report
  150. plot_pixel move.l  62(a0),d3       Grab the ink mask
  151.            btst    #0,d2           Find out if Y is odd
  152.            beq.s   find_word       It's even, mask is OK
  153.            swap    d3              Odd, so use other mask
  154. *      
  155. * Point A1 at the relevant word in video memory
  156. *
  157. find_word  move.l  50(a0),a1       A1 := screen RAM start
  158.            lsl.w   #7,d2           1 line= 2^7= 128 bytes
  159.            adda.w  d2,a1           A1 := line RAM start
  160.            moveq   #7,d2
  161.            and.w   d1,d2           Save X MOD 8 in D2
  162.            lsr.w   #3,d1           D1 := offset on line
  163.            add.w   d1,d1           Offset := 0-126 (EVEN)
  164.            adda.w  d1,a1           A1 -> screen RAM word
  165. *
  166. * Set the pixel in MODE 4 or 8, allowing for OVER -1
  167. *
  168. set_pixel  move.w  d7,d1           Select pixel mask
  169.            ror.w   d2,d1           Align pixel mask
  170.            and.w   d1,d3           D3 := 1 pixel of ink
  171.            btst    #3,66(a0)       Check for OVER -1
  172.            bne.s   overplot
  173.            not.w   d1              Mask out the rest
  174.            and.w   (a1),d1         Fetch the background
  175.            or.w    d3,d1           Insert the pixel
  176.            move.w  d1,(a1)         Store the combination
  177.            rts                      PLOT returns ERR.OK
  178. overplot   eor.w   d3,(a1)         Exclusive OR the pixel
  179.            rts
  180. *
  181. define     dc.w    2               Number of procs
  182.            dc.w    plot-*
  183.            dc.b    4,'PLOT'
  184.            dc.w    draw-*
  185.            dc.b    4,'DRAW'
  186.            dc.w    0,0,0           End of procs, no fns
  187.            end
  188.